/*
 * INSANE - Interactive Structural Analysis Environment
 *
 * Copyright (C) 2003-2004
 * Universidade Federal de Minas Gerais
 * Escola de Engenharia
 * Departamento de Engenharia de Estruturas
 *
 * Author's email :     insane@dees.ufmg.br
 * Author's Website :   http://www.dees.ufmg.br/insane
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-
 * 1307, USA.
 *
 */

package br.ufmg.dees.insane.ui.rich.postp.postp_view.dialog;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

import br.ufmg.dees.insane.commons.view.ExtensionFileFilter;
import br.ufmg.dees.insane.commons.view.ViewState;
import br.ufmg.dees.insane.model.postp.PostpModel;
import br.ufmg.dees.insane.model.postp.StepPostp;
import br.ufmg.dees.insane.persistence.PostpPersistence.PostpPersistenceAsXML;
import br.ufmg.dees.insane.ui.rich.postp.postp_view.DesktopPostp;
import br.ufmg.dees.insane.ui.rich.postp.postp_view.InterfacePostp;
import br.ufmg.dees.insane.ui.rich.postp.postp_view.LoadViewState;
import br.ufmg.dees.insane.ui.rich.postp.postp_view.LoadingSplashScreen;
import br.ufmg.dees.insane.ui.rich.postp.postp_view.PostpViewState;

/**
 * A class representing creation dialog on screen.<br>
 * @author Penna, Samuel & Pitangueira, Roque
 * @since september 2004
 */
public final class LoadPostpXMLFileDialog extends JFrame {
	
	/**
	 * Comment for <code>serialVersionUID</code>
	 */
	private static final long serialVersionUID = 1L;
	
	private DesktopPostp parent;
	private PostpModel postpModel;
	private StepPostp stepPostp;
	
	private JFileChooser fileChooser = new JFileChooser();
	private ExtensionFileFilter filter = new ExtensionFileFilter(new String[]{"xml"}, "XML Files");
	
	private Container container;
	private GridBagLayout layout;
	private GridBagConstraints constraints;
	
	private JCheckBox diskCheckBox = new JCheckBox("");
	private JCheckBox memoryCheckBox = new JCheckBox("");;
	private JCheckBox allStepsCheckBox = new JCheckBox("");;
	private DecimalField stepField;
	private JButton loadButton = new JButton("Load File");
	private JButton okButton;
	private JButton cancelButton;
	private JTextField pathFileField = new JTextField();
	
	private String path;
	private String name;
	private String contPath;
	private String contName;
	
	private NumberFormat numberFormat;
	private LoadViewState viewState;
	
	private int step;
	
//	*****************************************************************************
	
	public LoadPostpXMLFileDialog() {
		viewState = new LoadViewState();
		fileChooser.setFileFilter(filter);
		this.init();
	}
	
	public void init(){
		setUpFormat();
		this.setTitle("Load XML");
		Image ico = Toolkit.getDefaultToolkit().getImage(ClassLoader.getSystemResource("br/ufmg/dees/insane/images/Insane64.gif"));
		this.setIconImage(ico);
		
		container = this.getContentPane();
		this.setResizable(false);
		
		layout = new GridBagLayout();
		container.setLayout(layout);
		
		constraints = new GridBagConstraints();
		
		//JLabel onDisk = new JLabel("Work On Disk");
		ActionListener onDiskListener = new ChoiceListenerOnDisk();         
		diskCheckBox.addActionListener(onDiskListener);
		
		//JLabel onMemory = new JLabel("Work On Memory    ");
		ActionListener onMemoryListener = new ChoiceListenerOnMemory();         
		memoryCheckBox.addActionListener(onMemoryListener);
		
		JLabel allSteps = new JLabel("      All Steps   ");
		ActionListener allStepsListener = new ChoiceListenerAllSteps();         
		allStepsCheckBox.addActionListener(allStepsListener);
		allStepsCheckBox.setSelected(true);
		
		JLabel stepCount = new JLabel("      Step Gap:   ");
		stepField = new DecimalField(step,10,numberFormat);
		stepField.setMaximumSize(new Dimension(10,10));
		stepField.setPreferredSize(new Dimension(10,10));
		stepField.setMinimumSize(new Dimension(10,10));
		stepField.setSize(new Dimension(10,10));  
		stepField.setValue(1);
		if(allStepsCheckBox.isSelected()){
			stepField.setEnabled(false);	
		}
		
		loadButton = new JButton("Load Files");
		
		pathFileField = new JTextField();
		pathFileField.setEditable(true);
		pathFileField.setPreferredSize(new Dimension(150,20));
		
		okButton = new JButton("    OK    ");
		cancelButton = new JButton("Cancel");
		
//		********Work place panel***
		JPanel workPlacePane = new JPanel();
		GridLayout gridLayout1 = new GridLayout(2,1,0,0);
		workPlacePane.setLayout(gridLayout1);          
		workPlacePane.setPreferredSize(new Dimension(220,130));
		workPlacePane.setBorder(BorderFactory.createCompoundBorder(
				BorderFactory.createTitledBorder("Work Place"),
				BorderFactory.createEmptyBorder(2,2,2,2)));
		// workplace componets
		workPlacePane.add(diskCheckBox);
		//workPlacePane.add(onDisk);
		diskCheckBox.setText("     Work on disk");
		workPlacePane.add(memoryCheckBox);
		//workPlacePane.add(onMemory);
		memoryCheckBox.setText("     Work on Memory");
		
//		***StepConut panel***		
		JPanel stepCountPane = new JPanel();
		GridLayout gridLayout2 = new GridLayout(2,1,0,0);
		stepCountPane.setLayout(gridLayout2);          
		stepCountPane.setPreferredSize(new Dimension(220,130));
		stepCountPane.setBorder(BorderFactory.createCompoundBorder(
				BorderFactory.createTitledBorder("Step Control"),
				BorderFactory.createEmptyBorder(2,2,2,2)));
//		workplace componets
		stepCountPane.add(allSteps);
		stepCountPane.add(allStepsCheckBox);
		stepCountPane.add(stepCount);
		stepCountPane.add(stepField);
		
//		adicionando workPlacePane 
		constraints.fill = GridBagConstraints.BOTH;
		addComponent(workPlacePane,0,0,3,3);
//		adicionando stepCountPane 
		constraints.fill = GridBagConstraints.BOTH;
		addComponent(stepCountPane,0,4,3,3);
//		adicionando espa�o
		constraints.fill = GridBagConstraints.BOTH;
		addComponent(new JLabel("   "),2,0,6,1);
//		adicionando loadButton
		constraints.fill = GridBagConstraints.BOTH;
		addComponent(loadButton,3,0,1,1);
//		adicionando JLabel
		constraints.fill = GridBagConstraints.BOTH;
		addComponent(new JLabel("   Path: "),3,1,1,1);		    
//		adicionando pathFileField
		constraints.fill = GridBagConstraints.BOTH;
		addComponent(pathFileField,3,2,5,1);	 
//		adicionando espa�o
		constraints.fill = GridBagConstraints.BOTH;
		addComponent(new JLabel("   "),3,2,1,1);
//		adicionando espa�o
		constraints.fill = GridBagConstraints.BOTH;
		addComponent(new JLabel("   "),4,2,4,1);
//		adicionando okButton
		constraints.fill = GridBagConstraints.BOTH;
		addComponent(okButton,5,2,1,1);
//		adicionando espa�o
		constraints.fill = GridBagConstraints.BOTH;
		addComponent(new JLabel("   "),5,3,1,1);
//		adicionando espa�o
		constraints.fill = GridBagConstraints.BOTH;
		addComponent(cancelButton,5,4,1,1);
		
		loadButton.addActionListener(
				new ActionListener(){
					public void actionPerformed(ActionEvent event){
						int retVal = fileChooser.showDialog(new JFrame(), "Load");
						if (retVal == JFileChooser.APPROVE_OPTION) {
							//Getting the file name
							String s = fileChooser.getSelectedFile().getName();
							
							//Getting the file extension
							String ext = new String();
							int i = s.lastIndexOf('.');
							if (i > 0 &&  i < s.length() - 1) {
								ext = s.substring(i+1).toLowerCase();
							}
							
							//Comparing the extension
							if (!ext.equals("xml")) {
								s = s + ".xml";
								File file = fileChooser.getSelectedFile();
								//Changing the file in case of no good extensions
								fileChooser.setSelectedFile(new File(file.getParent() + File.separator + s));
							}
						}
						if(fileChooser.getSelectedFile()!=null){
							path = fileChooser.getSelectedFile().getParent();
							contPath = fileChooser.getSelectedFile().getParent();
							name = fileChooser.getSelectedFile().getName();
							contName = fileChooser.getSelectedFile().getName();
							pathFileField.setText(fileChooser.getSelectedFile().getParent());
						}
					}
				});
		
		okButton.addActionListener(
				new ActionListener(){
					public void actionPerformed(ActionEvent event){
						if(path==null){
							pathErrMessage();
						}else{
							if(checkStepFile(name)){
								approvedPerform();
								close(event);
							}else{
								String message = "";
								message += "Couldn't open file!\n";
								message += "There are no STEPS to load!\n";
								message += "Use ''import command'' or set STEPS files!";
								JOptionPane.showMessageDialog(parent, message, "Error Message", JOptionPane.ERROR_MESSAGE);
								close(event);
							}
						}
					}
				});
		
		cancelButton.addActionListener(
				new ActionListener(){
					public void actionPerformed(ActionEvent event){
						close(event);
					}
				});
		
		allStepsCheckBox.setSelected(true);
		diskCheckBox.setSelected(false);
		memoryCheckBox.setSelected(true);
		
		this.setSize(410,200);
		this.setLocation(200,200);
		this.setVisible(true);
	}
	
	private void addComponent(Component component, int row, int column, int width, int height){
		constraints.gridx = column;
		constraints.gridy = row;
		
		constraints.gridwidth = width;
		constraints.gridheight = height;
		
		layout.setConstraints(component, constraints);
		container.add(component);
		
	}
	
	public void pathErrMessage(){
		JOptionPane.showMessageDialog(this,"No path was found!", "Error Message", JOptionPane.ERROR_MESSAGE);
	}
	
	public boolean checkStepFile(String s){
		boolean contains;
		if(s.contains("-STEP-")){
			contains = true;
		}else{
			contains = false;
		}
		return contains;
	}
	
	public void close(ActionEvent event){
		this.dispose();
	}
	
	public void approvedPerform(){
		LoadDialog loadDialog = new LoadDialog();
		Thread dlg = new Thread(loadDialog);
		dlg.start();
	}
	
	/**
	 * Sets the number formater
	 */
	private void setUpFormat() {
		numberFormat = (DecimalFormat)NumberFormat.getNumberInstance(Locale.UK);
		numberFormat.setMaximumFractionDigits(3);
	}
	
	private class ChoiceListenerAllSteps implements ActionListener{
		public void actionPerformed(ActionEvent event){
			if(allStepsCheckBox.isSelected()){
				stepField.setEnabled(false);
				stepField.setEditable(false);
				stepField.repaint();
			}
			if(!allStepsCheckBox.isSelected()){
				stepField.setEnabled(true);
				stepField.setEditable(true);
				stepField.repaint();
			}
		}    
	}
	
	private class ChoiceListenerOnDisk implements ActionListener{
		public void actionPerformed(ActionEvent event){
			if(diskCheckBox.isSelected()){
				diskCheckBox.setSelected(true);
				memoryCheckBox.setSelected(false);
			}
		}    
	}
	
	private class ChoiceListenerOnMemory implements ActionListener{
		public void actionPerformed(ActionEvent event){
			if(memoryCheckBox.isSelected()){
				diskCheckBox.setSelected(false);
				memoryCheckBox.setSelected(true);
			} 
		}    
	}
	
	
	/**
	 * The method set the field parent from the parameter parent.
	 * @param parent The parent to set.
	 */
	public void setParent(DesktopPostp parent) {
		this.parent = parent;
	}
	
	/**
	 * The method return the state.
	 * @return Returns The state.
	 */
	public ViewState getViewState() {
		return viewState;
	}
	
	/**
	 * The method set the field state from the parameter state.
	 * @param state The state to set.
	 */
	public void setViewState(LoadViewState state) {
		this.viewState = state;
	}
	
	
	class LoadDialog implements Runnable{
		
		LoadingDialog loadDialog;
		
		public void run() {
			
			if(memoryCheckBox.isSelected()){
				loadDialog = new LoadingDialog(parent);
				loadDialog.setVisible(true);
			}
			
			//boolean isValid = true;
			PostpPersistenceAsXML p = new PostpPersistenceAsXML();
			
			DecimalFormat fmt = new DecimalFormat();
			fmt.applyPattern("000");
			
			int indexName = Integer.parseInt(name.substring(name.indexOf("STEP-")+5,name.indexOf("STEP-")+8));
			int cont = Integer.parseInt(name.substring(name.indexOf("STEP-")+5,name.indexOf("STEP-")+8));
			int loadCont = Integer.parseInt(name.substring(name.indexOf("STEP-")+5,name.indexOf("STEP-")+8));
			postpModel = new PostpModel();
			postpModel.setLabel(name.replaceAll("-STEP-"+fmt.format(indexName)+".xml",""));  
			parent.setInterface();
			
			int contFiles = 0;
			
			File loadFile = new File("");
			File file = new File("");
			
			if(memoryCheckBox.isSelected()){
				
				InterfacePostp intFrame;
				String aux = name;
				
				file = fileChooser.getSelectedFile();
				loadFile = fileChooser.getSelectedFile();
				
				if(((DesktopPostp)parent).getModelList().getModelList().containsKey(postpModel.getLabel())){
					
					while(fileChooser.getSelectedFile().exists()){
						file = new File(path+File.separator+aux);
						fileChooser.setSelectedFile(file);
						if(allStepsCheckBox.isSelected()){
							contFiles++;
							cont++;
						}else{
							contFiles++;
							cont+=(int)stepField.getValue();
						}	
						
						aux = name.replaceAll(fmt.format(indexName)+"",""+fmt.format(cont));
					}
					
					loadDialog.getLoadBar().setProgressCont(contFiles-1);
					
					for(int i=0;i<contFiles-1;i++){	
						this.advanceSplashProgress();
						aux = name.replaceAll(fmt.format(indexName)+"",""+fmt.format(loadCont));
						
						p.fillInsaneFromFile(path+File.separator+aux);
						
						stepPostp = new StepPostp();
						stepPostp = p.getStep();
						postpModel.addStep(stepPostp);
						if(allStepsCheckBox.isSelected()){
							loadCont++;
						}else{
							loadCont+=(int)stepField.getValue();
						}	
						loadDialog.getScrollPane().getVerticalScrollBar().setValue(loadDialog.getTextArea().getHeight()-1);
						loadDialog.getTextArea().append("  "+aux+"\n");
						loadDialog.getTextArea().repaint();
					}
					postpModel.setLabel(name.replaceAll("-STEP-"+fmt.format(indexName)+".xml",""));
					LoadingSplashScreen.getInstance().finish();
					
					((DesktopPostp)parent).getModelList().removeModel(postpModel.getLabel());
					((DesktopPostp)parent).getModelList().putModel(postpModel.getLabel(),postpModel);
					
					intFrame = new InterfacePostp();
					intFrame.validate();
					intFrame.setModel((StepPostp)postpModel.getStepList().get(0));
					intFrame.setPostpModel(postpModel);
					intFrame.setTitle(postpModel.getLabel());
					(parent).addInternalFrame(intFrame);
					intFrame.toFront();
					
					loadDialog.dispose();
					
				}else{
					while(fileChooser.getSelectedFile().exists()){
						file = new File(path+File.separator+aux);
						fileChooser.setSelectedFile(file);
						if(allStepsCheckBox.isSelected()){
							contFiles++;
							cont++;
						}else{
							contFiles++;
							cont+=(int)stepField.getValue();
						}	
						
						aux = name.replaceAll(fmt.format(indexName)+"",""+fmt.format(cont));
					}
					
					loadDialog.getLoadBar().setProgressCont(contFiles-1);
					
					for(int i=0;i<contFiles-1;i++){	
						this.advanceSplashProgress();
						aux = name.replaceAll(fmt.format(indexName)+"",""+fmt.format(loadCont));
						
						p.fillInsaneFromFile(path+File.separator+aux);
						
						stepPostp = new StepPostp();
						stepPostp = p.getStep();
						postpModel.addStep(stepPostp);
						if(allStepsCheckBox.isSelected()){
							loadCont++;
						}else{
							loadCont+=(int)stepField.getValue();
						}	
						loadDialog.getScrollPane().getVerticalScrollBar().setValue(loadDialog.getTextArea().getHeight()-1);
						loadDialog.getTextArea().append("  "+aux+"\n");
						loadDialog.getTextArea().repaint();
					}
					postpModel.setLabel(name.replaceAll("-STEP-"+fmt.format(indexName)+".xml",""));
					LoadingSplashScreen.getInstance().finish();
					intFrame = new InterfacePostp();
					intFrame.validate();
					intFrame.setModel((StepPostp)postpModel.getStepList().get(0));
					intFrame.setPostpModel(postpModel);
					intFrame.setTitle(postpModel.getLabel());
					(parent).addInternalFrame(intFrame);
					intFrame.toFront();
					((DesktopPostp)parent).getModelList().putModel(postpModel.getLabel(),postpModel);
					
					loadDialog.dispose();
					
				}
				
				((PostpViewState)intFrame.getView().getViewState()).getLoadViewState().setPath(fileChooser.getSelectedFile().getPath());
				((PostpViewState)intFrame.getView().getViewState()).getLoadViewState().setOnDiskOpt(false);
				((PostpViewState)intFrame.getView().getViewState()).getLoadViewState().setOnMemoryOpt(true);
				((PostpViewState)intFrame.getView().getViewState()).getLoadViewState().setStepGap((int)stepField.getValue());
				
			}else{
				
				InterfacePostp intFrame = new InterfacePostp();
				
				String aux = contName;
				file = fileChooser.getSelectedFile();
				loadFile = fileChooser.getSelectedFile();
				while(file.exists()){
					((PostpViewState)intFrame.getView().getViewState()).getLoadViewState().getStepLoaded().add(contPath+File.separator+aux);
					if(allStepsCheckBox.isSelected()){
						contFiles++;
						cont++;
					}else{
						contFiles++;
						cont+=(int)stepField.getValue();
					}
					aux = contName.replaceAll(fmt.format(indexName)+"",""+fmt.format(cont));
					file = new File(contPath+File.separator+aux);
				}
				
				
				postpModel.setLabel(name.replaceAll("-STEP-"+fmt.format(indexName)+".xml",""));
				
				if(((DesktopPostp)parent).getModelList().getModelList().containsKey(postpModel.getLabel())){
					((DesktopPostp)parent).getModelList().removeModel(postpModel.getLabel());
					((DesktopPostp)parent).getModelList().putModel(postpModel.getLabel(),postpModel);
					p.fillInsaneFromFile(loadFile.getPath());
					stepPostp = new StepPostp();
					stepPostp = p.getStep();
					postpModel.addStep(stepPostp);
					intFrame.validate();
					intFrame.setModel((StepPostp)postpModel.getStepList().get(0));
					intFrame.setPostpModel(postpModel);
					intFrame.setTitle(postpModel.getLabel());
					(parent).addInternalFrame(intFrame);
					intFrame.toFront();
					
					String message = "A model with same name was found and overrided!"; 
					JOptionPane.showMessageDialog(parent, message, "Warning", JOptionPane.INFORMATION_MESSAGE);
					
				}else{
					p.fillInsaneFromFile(loadFile.getPath());
					stepPostp = new StepPostp();
					stepPostp = p.getStep();
					postpModel.addStep(stepPostp);
					intFrame.validate();
					intFrame.setModel((StepPostp)postpModel.getStepList().get(0));
					intFrame.setPostpModel(postpModel);
					intFrame.setTitle(postpModel.getLabel());
					(parent).addInternalFrame(intFrame);
					intFrame.toFront();
					((DesktopPostp)parent).getModelList().putModel(postpModel.getLabel(),postpModel);
				}
				
				((PostpViewState)intFrame.getView().getViewState()).getLoadViewState().setPath(name);
				((PostpViewState)intFrame.getView().getViewState()).getLoadViewState().setPath(fileChooser.getSelectedFile().getAbsolutePath());
				((PostpViewState)intFrame.getView().getViewState()).getLoadViewState().setOnDiskOpt(true);
				((PostpViewState)intFrame.getView().getViewState()).getLoadViewState().setOnMemoryOpt(false);
				((PostpViewState)intFrame.getView().getViewState()).getLoadViewState().setAllStepsOpt(allStepsCheckBox.isSelected());
				((PostpViewState)intFrame.getView().getViewState()).getLoadViewState().setStepGap((int)stepField.getValue());
				
			}
			
		}
		
		public void advanceSplashProgress() {
			if(loadDialog.getLoadBar() != null)
				loadDialog.getLoadBar().advance();
		}
		
	}
	
//	*****************************************************************************
}//end of this class




